#ifndef __WXGBSIZER_H__
#define __WXGBSIZER_H__

#include "wx/sizer.h"

class wxGBPosition {
  public:
    wxGBPosition() : m_row( 0 ), m_col( 0 ) {}
    wxGBPosition( int row, int col ) : m_row( row ), m_col( col ) {}



    int GetRow() const { return m_row; }
    int GetCol() const { return m_col; }
    void SetRow( int row ) { m_row = row; }
    void SetCol( int col ) { m_col = col; }
    bool operator==( const wxGBPosition& p ) const { return m_row == p.m_row && m_col == p.m_col; }
    bool operator!=( const wxGBPosition& p ) const { return !( *this == p ); }

  private:
    int m_row;
    int m_col;
};

class wxGBSpan {
  public:
    wxGBSpan() : m_rowspan( 1 ), m_colspan( 1 ) {}
    wxGBSpan( int rowspan, int colspan ) : m_rowspan( rowspan ), m_colspan( colspan ) {}
    int GetRowspan() const { return m_rowspan; }
    int GetColspan() const { return m_colspan; }
    void SetRowspan( int rowspan ) { m_rowspan = rowspan; }
    void SetColspan( int colspan ) { m_colspan = colspan; }
    bool operator==( const wxGBSpan& o ) const { return m_rowspan == o.m_rowspan && m_colspan == o.m_colspan; }
    bool operator!=( const wxGBSpan& o ) const { return !( *this == o ); }
  private:
    int m_rowspan;
    int m_colspan;
};


extern const wxGBSpan wxDefaultSpan;

class wxGridBagSizer;

class wxGBSizerItem : public wxSizerItem {
  public:

    wxGBSizerItem( int width,
                   int height,
                   const wxGBPosition& pos,
                   const wxGBSpan& span,
                   int flag,
                   int border,
                   wxObject* userData );


    wxGBSizerItem( wxWindow *window,
                   const wxGBPosition& pos,
                   const wxGBSpan& span,
                   int flag,
                   int border,
                   wxObject* userData );


    wxGBSizerItem( wxSizer *sizer,
                   const wxGBPosition& pos,
                   const wxGBSpan& span,
                   int flag,
                   int border,
                   wxObject* userData );


    wxGBSizerItem();



    wxGBPosition GetPos() const { return m_pos; }
    void GetPos( int& row, int& col ) const;


    wxGBSpan GetSpan() const { return m_span; }
    void GetSpan( int& rowspan, int& colspan ) const;





    bool SetPos( const wxGBPosition& pos );





    bool SetSpan( const wxGBSpan& span );


    bool Intersects( const wxGBSizerItem& other );


    bool Intersects( const wxGBPosition& pos, const wxGBSpan& span );


    void GetEndPos( int& row, int& col );


    wxGridBagSizer* GetGBSizer() const { return m_gbsizer; }
    void SetGBSizer( wxGridBagSizer* sizer ) { m_gbsizer = sizer; }


  protected:
    wxGBPosition    m_pos;
    wxGBSpan        m_span;
    wxGridBagSizer* m_gbsizer;
  private:
    DECLARE_DYNAMIC_CLASS( wxGBSizerItem )
    DECLARE_NO_COPY_CLASS( wxGBSizerItem )
};

class wxGridBagSizer : public wxFlexGridSizer {
  public:
    wxGridBagSizer( int vgap = 0, int hgap = 0 );
    wxSizerItem* Add( wxWindow *window,
                      const wxGBPosition& pos,
                      const wxGBSpan& span = wxDefaultSpan,
                      int flag = 0,
                      int border = 0,
                      wxObject* userData = NULL );
    wxSizerItem* Add( wxSizer *sizer, const wxGBPosition& pos, const wxGBSpan& span = wxDefaultSpan, int flag = 0,
                      int border = 0, wxObject* userData = NULL );
    wxSizerItem* Add( int width, int height, const wxGBPosition& pos, const wxGBSpan& span = wxDefaultSpan,
                      int flag = 0, int border = 0, wxObject* userData = NULL );
    wxSizerItem* Add( wxGBSizerItem *item );
    wxSize GetEmptyCellSize() const          { return m_emptyCellSize; }
    void SetEmptyCellSize( const wxSize& sz )  { m_emptyCellSize = sz; }
    wxSize GetCellSize( int row, int col ) const;
    wxGBPosition GetItemPosition( wxWindow *window );
    wxGBPosition GetItemPosition( wxSizer *sizer );
    wxGBPosition GetItemPosition( size_t index );
    bool SetItemPosition( wxWindow *window, const wxGBPosition& pos );
    bool SetItemPosition( wxSizer *sizer, const wxGBPosition& pos );
    bool SetItemPosition( size_t index, const wxGBPosition& pos );
    wxGBSpan GetItemSpan( wxWindow *window );
    wxGBSpan GetItemSpan( wxSizer *sizer );
    wxGBSpan GetItemSpan( size_t index );
    bool SetItemSpan( wxWindow *window, const wxGBSpan& span );
    bool SetItemSpan( wxSizer *sizer, const wxGBSpan& span );
    bool SetItemSpan( size_t index, const wxGBSpan& span );
    wxGBSizerItem* FindItem( wxWindow* window );
    wxGBSizerItem* FindItem( wxSizer* sizer );
    wxGBSizerItem* FindItemAtPosition( const wxGBPosition& pos );
    wxGBSizerItem* FindItemAtPoint( const wxPoint& pt );
    wxGBSizerItem* FindItemWithData( const wxObject* userData );
    virtual void RecalcSizes();
    virtual wxSize CalcMin();
    bool CheckForIntersection( wxGBSizerItem* item, wxGBSizerItem* excludeItem = NULL );
    bool CheckForIntersection( const wxGBPosition& pos, const wxGBSpan& span, wxGBSizerItem* excludeItem = NULL );
    virtual wxSizerItem* Add( wxWindow *window, int proportion = 0, int flag = 0, int border = 0, wxObject* userData = NULL );
    virtual wxSizerItem* Add( wxSizer *sizer, int proportion = 0, int flag = 0, int border = 0, wxObject* userData = NULL );
    virtual wxSizerItem* Add( int width, int height, int proportion = 0, int flag = 0, int border = 0, wxObject* userData = NULL );
    virtual wxSizerItem* Add( wxSizerItem *item );
    virtual wxSizerItem* Insert( size_t index, wxWindow *window, int proportion = 0, int flag = 0, int border = 0, wxObject* userData = NULL );
    virtual wxSizerItem* Insert( size_t index, wxSizer *sizer, int proportion = 0, int flag = 0, int border = 0, wxObject* userData = NULL );
    virtual wxSizerItem* Insert( size_t index, int width, int height, int proportion = 0, int flag = 0, int border = 0, wxObject* userData = NULL );
    virtual wxSizerItem* Insert( size_t index, wxSizerItem *item );
    virtual wxSizerItem* Prepend( wxWindow *window, int proportion = 0, int flag = 0, int border = 0, wxObject* userData = NULL );
    virtual wxSizerItem* Prepend( wxSizer *sizer, int proportion = 0, int flag = 0, int border = 0, wxObject* userData = NULL );
    virtual wxSizerItem* Prepend( int width,  int height,  int proportion = 0,  int flag = 0,  int border = 0,  wxObject* userData = NULL );
    virtual wxSizerItem* Prepend( wxSizerItem *item );
  protected:
    wxGBPosition FindEmptyCell();
    void AdjustForOverflow();
    wxSize m_emptyCellSize;
  private:
    DECLARE_CLASS( wxGridBagSizer )
    DECLARE_NO_COPY_CLASS( wxGridBagSizer )
};


#endif
